﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Csla.Core;
using OpenExpressApp.Editors;
using OpenExpressApp.MetaModel;
using OpenExpressApp.Module.View;
using OpenExpressApp.Template;
using OpenExpressApp.Types;
using Csla.Reflection;
using System.ComponentModel;

namespace OpenExpressApp
{
    /// <summary>
    /// 对象的视图
    /// </summary>
    public abstract class ObjectView : IActiveCurrentObjectContext, IDataContext, IObjectView
    {
        private Dictionary<Type, IWindowTemplate> _padDict;

        private IViewDataLoader _controller;

        private Type _entityType;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="entityType">这个视图对应这个业务模型类型</param>
        public ObjectView(Type entityType)
        {
            this._entityType = entityType;
            this.RegionType = RegionType.Data;//默认为数据区域
        }

        public Dictionary<Type, IWindowTemplate> PadDict
        {
            get
            {
                if (null == _padDict)
                {
                    _padDict = new Dictionary<Type, IWindowTemplate>();
                }
                return _padDict;
            }
        }

        /// <summary>
        /// 区域的类型
        /// </summary>
        public RegionType RegionType { get; set; }

        /// <summary>
        /// 为这个View加载数据的对象
        /// </summary>
        public IViewDataLoader DataLoader
        {
            get
            {
                Debug.Assert(null != _controller, string.Format(@"View: {0} 的 Controller不能为空", BOType.Name));
                return _controller;
            }
            set
            {
                _controller = value;
            }
        }

        /// <summary>
        /// 这个视图作为子视图时，对应的父Model中的属性名称
        /// </summary>
        public string PropertyName { get; protected set; }

        /// <summary>
        /// 当前View对应这个业务模型类型
        /// </summary>
        public Type BOType
        {
            get
            {
                return this._entityType;
            }
        }

        #region PropertyEditors

        private List<IPropertyEditor> _propertyEditors = new List<IPropertyEditor>();

        /// <summary>
        /// 所有的这个View使用的属性Editor
        /// </summary>
        public IList<IPropertyEditor> PropertyEditors
        {
            get
            {
                return this._propertyEditors.AsReadOnly();
            }
        }

        /// <summary>
        /// 找到指定属性的Editor。
        /// 如果找不到，则把editor加入并返回。
        /// </summary>
        /// <param name="info"></param>
        /// <param name="editor"></param>
        /// <returns></returns>
        public IPropertyEditor AddPropertyEditor(IPropertyEditor editor)
        {
            var result = this._propertyEditors.FirstOrDefault(e => e.PropertyInfo == editor.PropertyInfo);
            if (result == null)
            {
                result = editor;
                this._propertyEditors.Add(result);
            }
            return result;
        }

        /// <summary>
        /// 在View中寻找指定属性的Editor
        /// </summary>
        /// <param name="conView"></param>
        /// <param name="propertyName">找这个属性对应的Editor</param>
        /// <returns></returns>
        public IPropertyEditor FindPropertyEditor(string propertyName)
        {
            return this._propertyEditors.FirstOrDefault(e => e.PropertyInfo.Name == propertyName);
        }

        #endregion

        #region CurrentObject

        /// <summary>
        /// 当前的对象
        /// 
        /// 空实现，子类实现。
        /// </summary>
        public abstract object CurrentObject { get; set; }

        /// <summary>
        /// CurrentObject.Id
        /// </summary>
        public Guid? CurrentID
        {
            get
            {
                var currentObject = this.CurrentObject;
                return currentObject == null ? default(Guid?) : currentObject.GetPropertyValue<Guid>(DBConvention.FieldName_Id);
            }
        }

        public event EventHandler CurrentObjectChanged;

        /// <summary>
        /// 刷新CurrentObject
        /// 子类实现
        /// </summary>
        public abstract void RefreshCurrentObject();

        /// <summary>
        /// CurrentObjectChanged事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void OnCurrentObjectChanged()
        {
            this.SetChildrenData();

            if (this.CurrentObjectChanged != null)
            {
                this.CurrentObjectChanged(this, EventArgs.Empty);
            }
        }

        #endregion

        #region Data

        public event EventHandler DataChanged;

        private object _data;

        /// <summary>
        /// 绑定的对象
        /// </summary>
        public object Data
        {
            get
            {
                return _data;
            }
            set
            {
                if (this._data != value)
                {
                    this.OnDataChanging();
                    this._data = value;
                    this.OnDataChanged();
                }
            }
        }

        protected virtual void OnDataChanging() { }

        protected virtual void OnDataChanged()
        {
            if (this.DataChanged != null)
            {
                this.DataChanged(this, EventArgs.Empty);
            }
        }

        #endregion

        #region Load Data

        /// <summary>
        /// 是否允许加载数据
        /// </summary>
        protected virtual bool AllowLoadData
        {
            get
            {
                return null != this.Parent &&
                    this.Parent._control != null &&
                    null != this.Parent.CurrentObject;
            }
        }

        /// <summary>
        /// 加载数据
        /// </summary>
        public virtual void LoadData()
        {
            if (AllowLoadData)
            {
                this.Data = this.Parent.CurrentObject.GetPropertyValue(PropertyName);
            }
        }

        /// <summary>
        /// 绑定这个视图的子视图
        /// 
        /// 把CurrentObject中对应每个子视图的属性，取值出来，并赋值给子视图
        /// </summary>
        /// <param name="view"></param>
        protected void SetChildrenData()
        {
            foreach (var child in this.ChildViews)
            {
                //把CurrentObject中对应每个子视图的属性，取值出来，并赋值给子视图
                //child.Data = (this.CurrentObject as BusinessBase).GetPropertyValue(child.PropertyName);
                //考虑细表大采用懒加载属性时，这里只清空细表，在TabItem可见时更新当前ChildView.Data，以免一次全部装载所有细表
                child.Data = null;
                child.ReloadActiveData();
            }
        }

        /// <summary>
        /// 为活动状态时才加载数据
        /// </summary>
        private void ReloadActiveData()
        {
            if (this._isActive)
            {
                this.LoadData();
            }
        }

        #endregion

        #region IsVisible

        private bool _isVisible = true;

        /// <summary>
        /// 当前的视图，是否可见。
        /// 
        /// 注意：暂时不支持直接进行设置以控件。set方法暂留。
        /// </summary>
        public bool IsVisible
        {
            get
            {
                return this._isVisible;
            }
            set
            {
                if (this._isVisible != value)
                {
                    this.SetIsVisible(value);

                    if (value)
                    {
                        //保证
                        if (this._parent != null)
                        {
                            this._parent.EnsureChildActived();
                        }
                    }
                    else
                    {
                        //如果不可见，则取消激活。
                        this.IsActive = false;
                    }
                }
            }
        }

        /// <summary>
        /// 直接设置IsVisible的值
        /// </summary>
        /// <param name="value"></param>
        private void SetIsVisible(bool value)
        {
            if (this._isVisible != value)
            {
                this._isVisible = value;

                this.OnIsVisibleChanged();
            }
        }

        public event EventHandler IsVisibleChanged;

        protected virtual void OnIsVisibleChanged()
        {
            if (this.IsVisibleChanged != null)
            {
                this.IsVisibleChanged(this, EventArgs.Empty);
            }
        }

        #endregion

        #region IsActive

        private bool _isActive;

        /// <summary>
        /// 当前视图是否处于活动状态，TabItem处于当前页签时为isactive。
        /// 默认false
        /// </summary>
        public bool IsActive
        {
            get
            {
                return this._isActive;
            }
            set
            {
                if (this._isActive != value)
                {
                    if (value)
                    {
                        //Active 的ChildView肯定是可见的。
                        this.SetIsVisible(true);
                    }

                    this.SetIsActive(value);

                    if (this._parent != null)
                    {
                        if (value)
                        {
                            this._parent.ActiveChild(this);
                        }
                        else
                        {
                            //激活一个默认的ChildView
                            this._parent.DeactiveChild(this);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 直接设置IsActive的值
        /// </summary>
        /// <param name="value"></param>
        private void SetIsActive(bool value)
        {
            if (this._isActive != value)
            {
                this._isActive = value;

                if (value)
                {
                    //加载数据
                    if (this._data == null)
                    {
                        this.LoadData();
                    }
                }

                this.OnIsActiveChanged();
            }
        }

        public event EventHandler IsActiveChanged;

        protected virtual void OnIsActiveChanged()
        {
            if (this.IsActiveChanged != null)
            {
                this.IsActiveChanged(this, EventArgs.Empty);
            }
        }

        /// <summary>
        /// 激活某个孩子视图
        /// 
        /// 同时把其它子视图设置为“未激活”。
        /// </summary>
        /// <param name="child"></param>
        private void ActiveChild(ObjectView child)
        {
            for (int i = 0, c = this._childViews.Count; i < c; i++)
            {
                var childView = this._childViews[i];
                childView.SetIsActive(childView == child);
            }
        }

        /// <summary>
        /// 当有孩子可见时，激活一个孩子。
        /// </summary>
        private void EnsureChildActived()
        {
            //如果已经有视图被激活，忽略此次请求。
            if (this._childViews.Any(c => c.IsActive)) return;

            this.ActiveDefaultChild();
        }

        /// <summary>
        /// 激活一个默认的孩子视图
        /// </summary>
        private void ActiveDefaultChild()
        {
            //找到第一个可见的孩子，激活它。
            for (int i = 0, c = this._childViews.Count; i < c; i++)
            {
                var childView = this._childViews[i];
                if (childView.IsVisible)
                {
                    childView.SetIsActive(true);
                    return;
                }
            }
        }

        /// <summary>
        /// 去除某个孩子视图的激活状态
        /// 
        /// 同时把其它子视图设置为“未激活”。
        /// </summary>
        /// <param name="child"></param>
        private void DeactiveChild(ObjectView child)
        {
            this.EnsureChildActived();
        }

        #endregion

        #region Parent View & Child View

        private ObjectView _parent;

        private List<ObjectView> _childViews = new List<ObjectView>();

        /// <summary>
        /// 可以包含多个细表ListView
        /// </summary>
        public IList<ObjectView> ChildViews
        {
            get
            {
                return this._childViews.AsReadOnly();
            }
        }

        /// <summary>
        /// 作为子视图和查询视图时有Parent
        /// </summary>
        public ObjectView Parent
        {
            get
            {
                return this._parent;
            }
            set
            {
                if (this._parent != value)
                {
                    if (this._parent != null)
                    {
                        this._parent._childViews.Remove(this);
                    }
                    this._parent = value;
                    if (value != null)
                    {
                        value._childViews.Add(this);
                    }
                }
            }
        }

        /// <summary>
        /// 添加子视图
        /// </summary>
        /// <param name="view"></param>
        public void AddChildView(ObjectView view)
        {
            if (this._childViews.Contains(view) == false)
            {
                this._childViews.Add(view);
                if (view._parent != null)
                {
                    view._parent._childViews.Remove(view);
                }
                view._parent = this;

                if (this._childViews.Count == 1)
                {
                    view.SetIsActive(true);
                }
            }
        }

        /// <summary>
        /// 查找指定类型的子视图
        /// </summary>
        /// <param name="type">指定的视图</param>
        /// <param name="recur">是否递归在子控件中查询</param>
        /// <returns></returns>
        public ObjectView GetChildView(Type type, bool recur)
        {
            foreach (var item in this._childViews)
            {
                if (item.BOType == type)
                {
                    return item;
                }
                if (recur)
                {
                    ObjectView view = item.GetChildView(type, recur);
                    if (null != view)
                    {
                        return view;
                    }
                }
            }
            return null;
        }

        /// <summary>
        /// 查找根对象视图
        /// </summary>
        /// <returns></returns>
        public ObjectView GetRootView()
        {
            ObjectView root = this;
            while (null != root._parent)
            {
                root = root._parent;
            }
            return root;
        }

        /// <summary>
        /// 查找指定类型的父视图
        /// </summary>
        /// <typeparam name="TParent">要找的父视图所对应的类型</typeparam>
        /// <returns></returns>
        public ObjectView GetParentView<TParent>()
        {
            return this.GetParentView(typeof(TParent));
        }

        /// <summary>
        /// 查找指定类型的父视图
        /// </summary>
        /// <param name="type">要找的父视图所对应的类型</param>
        /// <returns></returns>
        public ObjectView GetParentView(Type type)
        {
            if (this._parent == null)
            {
                return null;
            }

            if (this._parent.BOType == type)
            {
                return this._parent;
            }

            //多对象树形可能存在多个type，对于子对象来说，Parent可能指向同一个View
            if (BOType == type)
            {
                return this;
            }

            ObjectView view = this._parent.GetParentView(type);
            if (null != view)
            {
                return view;
            }
            return null;
        }

        #endregion

        #region MouseDoubleClick

        public event EventHandler MouseDoubleClick;

        /// <summary>
        /// 子类通知这个ObjectView控件发生了MouseDoubleClick事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void OnMouseDoubleClick(EventArgs e)
        {
            if (MouseDoubleClick != null)
            {
                MouseDoubleClick(this, e);
            }
        }

        #endregion

        #region Create Control

        private object _control;

        /// <summary>
        /// 如果还没有创建Control，则调用CreateControl进行创建。
        /// </summary>
        public virtual object Control
        {
            get
            {
                if (this._control == null)
                {
                    this._control = this.CreateControl();
                }
                return _control;
            }
        }

        /// <summary>
        /// 创建当前ObjectView关联的Control
        /// 子类实现
        /// </summary>
        /// <returns></returns>
        protected abstract object CreateControl();

        #endregion

        #region IObjectView Members

        public Type EntityType
        {
            get
            {
                return this._entityType;
            }
        }

        public IList<IObjectView> ChildrenViews
        {
            get
            {
                return new ReadOnlyCollection<IObjectView>(this._childViews.Cast<IObjectView>().ToArray());
            }
        }

        IObjectView IObjectView.Parent
        {
            get
            {
                return this.Parent;
            }
            set
            {
                this.Parent = value as ObjectView;
            }
        }

        #endregion
    }
}